#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <functional>
#include <chrono>

#include <random>

using namespace std;

int main()
{
	{
		std::default_random_engine dre;

		std::uniform_int_distribution<int> di(10, 20);
		cout << "Random int [10, 20]: ";
		for (int i = 0; i < 20; ++i) 
		{
			std::cout << di(dre) << " ";
		}
		std::cout << "\n" << std::endl;

		std::uniform_real_distribution<double> dr(10, 20);
		cout << "Random float [10.0, 20.0): " <<endl;
		for (int i = 0; i < 8; ++i)
		{
			std::cout << dr(dre) << " ";
		}
		std::cout << "\n" << std::endl;

		std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		std::shuffle(v.begin(), v.end(), dre);
		cout << "shuffle: " << endl;
		for (int i = 0; i < v.size(); ++i) 
		{
			std::cout << v[i] << " ";
		}
		std::cout << std::endl;
	}
	cout << "1--------------------------\n" << endl;

	{
		std::default_random_engine dre;
		std::default_random_engine dre2;

		auto randomNum = [](std::default_random_engine& dre)
		{
			std::uniform_int_distribution<int> di(10, 99);
			for (int i = 0; i < 10; ++i)
			{
				cout << di(dre) << " ";
			}
			cout << endl;
		};
		randomNum(dre);
		randomNum(dre2);
		cout << endl;

		stringstream restate;
		restate << dre;
		//cout << restate.str() << endl;
		randomNum(dre);
		restate >> dre;
		randomNum(dre);
		cout << endl;

		std::default_random_engine dre3(dre);
		randomNum(dre);
		randomNum(dre3);
		cout << endl;

		cout << "      ";
		dre.discard(2);
		randomNum(dre);
		randomNum(dre3);


	}
	cout << "2--------------------------\n" << endl;


	{
		std::default_random_engine dre(chrono::system_clock::to_time_t(chrono::system_clock::now()));

		cout << "seed with time: ";
		std::uniform_int_distribution<int> di(10, 99);
		for (int i = 0; i < 10; ++i)
		{
			cout << di(dre) << " ";
		}
		cout << endl;

		std::random_device rd;
		std::uniform_int_distribution<int> di2(10, 99);
		cout << "random device: ";
		for (int i = 0; i < 10; ++i)
		{
			cout << di2(rd) << " ";
		}
		cout << endl;

	}
	cout << "3--------------------------\n" << endl;
}